/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package de.tor.tribes.reportserver.ui;

import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.validator.StringLengthValidator;
import com.vaadin.event.Action;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.LayoutEvents.LayoutClickEvent;
import com.vaadin.event.LayoutEvents.LayoutClickListener;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.DragAndDropWrapper;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.Label;
import com.vaadin.ui.Link;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Tree;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.CloseEvent;
import de.tor.tribes.reportserver.IReportInfoPanelListener;
import de.tor.tribes.reportserver.IShareListener;
import de.tor.tribes.reportserver.MyVaadinApplication;
import de.tor.tribes.reportserver.PersistenceImpl;
import de.tor.tribes.reportserver.util.ParserException;
import de.tor.tribes.reportserver.util.UIUtil;
import de.tor.tribes.reportserver.util.ZebraReportParser;
import de.tor.tribes.types.DSUnit;
import de.tor.tribes.types.ZebraGroup;
import de.tor.tribes.types.ZebraGroupMembership;
import de.tor.tribes.types.ZebraReport;
import de.tor.tribes.types.ZebraReportGroup;
import de.tor.tribes.types.ZebraReportAccessGrant;
import de.tor.tribes.types.ZebraRole;
import de.tor.tribes.types.ZebraUser;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 *
 * @author Torridity
 */
public class MainScreen extends CustomComponent implements Action.Handler, IShareListener, IReportInfoPanelListener {

    @Override
    public void fireReportDeleteEvent(ReportInfoPanel pSource) {
        for (ReportInfoPanel visibleReport : visibleReports) {
            if (visibleReport.isSelected() || visibleReport.equals(pSource)) {
                visibleReport.getReport().delete(getPersistence());
            }
        }
        getApplication().getMainWindow().showNotification("Berichte gelöscht", "Die gewählten Berichte wurden erfolgreich gelöscht.", Window.Notification.TYPE_TRAY_NOTIFICATION);
        loadReports();
    }

    private PersistenceImpl getPersistence() {
        if (persistence == null) {
            persistence = ((MyVaadinApplication) getApplication()).getPersistence();;
        }
        return persistence;
    }

    public void fireReportShareEvent(ReportInfoPanel pSource) {
        List<ZebraReport> reports = new LinkedList<ZebraReport>();
        for (ReportInfoPanel visibleReport : visibleReports) {
            if (visibleReport.isSelected() || visibleReport.equals(pSource)) {
                reports.add(visibleReport.getReport());
            }
        }
        shareWindow = new Window("Bericht(e) freigeben");
        shareWindow.addComponent(new ShareScreen(reports, this));
        shareWindow.setWidth("230px");
        shareWindow.setModal(true);
        getApplication().getMainWindow().addWindow(shareWindow);
        shareWindow.center();
    }

    public void fireChangeReportGroupEvent(ReportInfoPanel pSource, ZebraReportGroup pGroup) {
        for (ReportInfoPanel visibleReport : visibleReports) {
            if (visibleReport.isSelected() || visibleReport.equals(pSource)) {
                pGroup.addReport(visibleReport.getReportAccessGrant(), getPersistence());
            }
        }
        getApplication().getMainWindow().showNotification("Berichte verschoben", "Die gewählten Berichte wurden erfolgreich verschoben.", Window.Notification.TYPE_TRAY_NOTIFICATION);
        reload();
    }

    public void fireDeleteReportGroupEvent(ReportInfoPanel pSource, ZebraReportGroup pGroup) {
        if (pGroup != null) {
            if (currentGroupId == pGroup.getId()) {
                currentGroupId = -1l;
            }
            pGroup.delete(getPersistence());
            getApplication().getMainWindow().showNotification("Berichtgruppe gelöscht", "Die gewählte Gruppe und alle enthaltenen Berichte wurden erfolgreich gelöscht.", Window.Notification.TYPE_TRAY_NOTIFICATION);
            reload();
        }
    }

    public void fireSharedEvent() {
        getApplication().getMainWindow().removeWindow(shareWindow);
        getApplication().getMainWindow().showNotification("Freigabe erfolgreich", "Der Bericht wurde erfolgreich freigegeben.", Window.Notification.TYPE_TRAY_NOTIFICATION);
        shareWindow = null;
    }

    public void fireShareCanceledEvent() {
        getApplication().getMainWindow().removeWindow(shareWindow);
        shareWindow = null;
    }

    private enum NODE_TYPE {

        REPORT_ROOT, REPORT_GROUP, REPORT, SHARED_REPORT, MANAGEMENT_ROOT, USER_GROUP, GROUP_INVITATION, USER;
    }

    private enum VIEW_TYPE {

        REPORT, MANAGEMENT, SEARCH
    }
    private final Action READ_REPORT_ACTION = new Action("Neuen Bericht einlesen");
    private final Action DELETE_REPORT_GROUP_ACTION = new Action("Gruppe löschen");
    private final Action CREATE_REPORT_GROUP_ACTION = new Action("Gruppe erstellen...");
    private final Action ADD_SELECTED_TO_GROUP_ACTION = new Action("Gewählte Berichte der Gruppe hinzufügen");
    private final Action RELOAD_ACTION = new Action("Aktualisieren");
    private final Action CREATE_USER_GROUP_ACTION = new Action("Gruppe erstellen...");
    private final Action DELETE_USER_GROUP_ACTION = new Action("Gruppe auflösen");
    private final Action INVITE_USER_ACTION = new Action("Benutzer einladen");
    private final Action JOIN_GROUP_ACTION = new Action("Gruppe beitreten");
    private final Action WITHDRAW_INVITATION_ACTION = new Action("Einladung ablehnen");
    private final Action LEAVE_GROUP_ACTION = new Action("Gruppe verlassen");
    private final Action KICK_USER_ACTION = new Action("Benutzer entlassen");
    private final Action MODIFY_USER_ACTION = new Action("Rechte bearbeiten");
    private VerticalLayout mainLayout = null;
    private HorizontalSplitPanel hsplit;
    private Tree objectTree;
    private Window shareWindow;
    private VIEW_TYPE currentView = VIEW_TYPE.REPORT;
    private SearchScreen searchPanel;
    private List<ReportInfoPanel> visibleReports;
    private int currentReportPage = 0;
    private long currentGroupId = -1l;
    private PersistenceImpl persistence;

    private void initDB() {
        ZebraUser tester = getPersistence().findUserByName("test");
        ZebraGroup group = new ZebraGroup();
        group.setName("MyGroup");
        group.addAdmin(tester, getPersistence());
        getPersistence().persist(group);

        ZebraUser tester2 = new ZebraUser();
        tester2.setName("test2");
        tester2.setPlainPassword("test2");
        getPersistence().persistUser(tester2);
        ZebraGroup group2 = new ZebraGroup();
        group2.setName("OtherGroup");
        group2.addAdmin(tester2, getPersistence());
        getPersistence().persist(group2);
        group2.addMember(tester, getPersistence());
        DSUnit unit = new DSUnit();
        unit.setPlainName("axe");
        unit.setName("Axtkämpfer");
        unit.setAttack(12);
        unit.setDefense(5);
        unit.setDefenseArcher(3);

        getPersistence().persist(unit);

        /*  ZebraReport rep = new ZebraReport();
         ZebraReportGroup reportGroup1 = new ZebraReportGroup();
         reportGroup1.setName("MyGroup");
         reportGroup1.setOwner(tester);
         ((MyVaadinApplication)getApplication()).getPersistence().persist(reportGroup1);
         ZebraReportGroup reportGroup2 = new ZebraReportGroup();
         reportGroup2.setOwner(tester);
         reportGroup2.setName("MyGroup2");
         ((MyVaadinApplication)getApplication()).getPersistence().persist(reportGroup2);
         rep.addAttackerUnit(unit, 20);
         rep.addLostAttackerUnit(unit, 10);
         rep.setOwner(tester);
         rep.setAttacker("Test");
         rep.setDefender("Test");
         rep.setSent(0);
         rep.setSource("Test");
         rep.setTarget("Test");
         ((MyVaadinApplication)getApplication()).getPersistence().persist(rep);
         reportGroup1.addReport(rep);*/
    }

    public MainScreen() {
        buildLayout();
        DragAndDropWrapper pane = new DragAndDropWrapper(mainLayout);
        pane.setSizeFull();

        setCompositionRoot(pane);

        //setCompositionRoot(mainLayout);
        visibleReports = new LinkedList<ReportInfoPanel>();
    }

    private void buildLayout() {
        HorizontalLayout buttonBar = new HorizontalLayout();
        buttonBar.setSpacing(true);
        NativeButton reportView = new NativeButton();
        reportView.setWidth("50px");
        reportView.setHeight("50px");
        reportView.setDescription("Berichtansicht öffnen");
        reportView.setIcon(new ThemeResource("../zebra/img/scroll_large.png"));
        reportView.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                currentView = VIEW_TYPE.REPORT;
                reload();
            }
        });

        NativeButton managementView = new NativeButton();
        managementView.setWidth("50px");
        managementView.setHeight("50px");
        managementView.setDescription("Benutzer- und Gruppenverwaltung öffnen");
        managementView.setIcon(new ThemeResource("../zebra/img/users2_large.png"));
        managementView.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                currentView = VIEW_TYPE.MANAGEMENT;
                reload();
            }
        });
        NativeButton search = new NativeButton();
        search.setWidth("50px");
        search.setHeight("50px");
        search.setDescription("Berichtsuche öffnen");
        search.setIcon(new ThemeResource("../zebra/img/view.png"));
        search.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                currentView = VIEW_TYPE.SEARCH;
                reload();
                final Window w = new Window("Berichte suchen");
                w.setContent(searchPanel);
                w.setWidth("500px");
                w.center();
                getApplication().getMainWindow().addWindow(w);

                w.addListener(new Window.CloseListener() {
                    public void windowClose(CloseEvent e) {
                        getApplication().getMainWindow().removeWindow(w);
                        searchPanel.setParent(null);
                    }
                });
            }
        });

        NativeButton logout = new NativeButton();
        logout.setWidth("50px");
        logout.setHeight("50px");
        logout.setDescription("Abmelden");
        logout.setIcon(new ThemeResource("../zebra/img/exit.png"));
        logout.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                Window w = new Window("Parser Setup");
                w.setContent(new ParserConfigurationScreen(getPersistence()));
                getApplication().getMainWindow().addWindow(w);
                w.center();

                //getApplication().close();
            }
        });


        buttonBar.addComponent(reportView);
        buttonBar.addComponent(search);
        buttonBar.addComponent(managementView);
        buttonBar.addComponent(logout);

        buttonBar.setHeight("50px");

        objectTree = new Tree();
        objectTree.addContainerProperty("name", String.class, null);
        objectTree.addContainerProperty("type", NODE_TYPE.class, null);
        objectTree.addContainerProperty("id", Long.class, null);
        objectTree.addContainerProperty("icon", ThemeResource.class, null);
        objectTree.setItemCaptionPropertyId("name");
        objectTree.setItemIconPropertyId("icon");
        objectTree.addActionHandler(this);

        searchPanel = new SearchScreen();
        searchPanel.setSizeFull();

        objectTree.addListener(new ItemClickEvent.ItemClickListener() {
            public void itemClick(ItemClickEvent event) {
                if (event.getButton() == ItemClickEvent.BUTTON_LEFT) {
                    Long id = (Long) event.getItem().getItemProperty("id").getValue();
                    currentGroupId = id;
                    currentReportPage = 0;
                    loadReports();
                }
            }
        });

        hsplit = new HorizontalSplitPanel();
        hsplit.setSizeFull();
        hsplit.setImmediate(true);
        VerticalLayout treeLayout = new VerticalLayout();
        objectTree.setSizeFull();
        treeLayout.addComponent(objectTree);
        Panel treePanel = new Panel();
        treePanel.setContent(treeLayout);
        treePanel.setSizeFull();
        hsplit.addComponent(treePanel);

        hsplit.addComponent(new Label("Lade..."));
        hsplit.setSplitPosition(200f, UNITS_PIXELS);
        mainLayout = new VerticalLayout();
        mainLayout.setImmediate(true);
        mainLayout.setMargin(true);
        mainLayout.setSpacing(true);
        mainLayout.setSizeFull();
        mainLayout.addComponent(buttonBar);
        mainLayout.addComponent(hsplit);
        mainLayout.setExpandRatio(hsplit, 1.0f);
    }

    /* private void moveItem(Object sourceItemId, Object targetItemId) {
     Item source = objectTree.getItem(sourceItemId);
     Item target = objectTree.getItem(targetItemId);
     NODE_TYPE sourceType = (NODE_TYPE) source.getItemProperty("type").getValue();
     NODE_TYPE targetType = (NODE_TYPE) target.getItemProperty("type").getValue();

     if (sourceType.equals(NODE_TYPE.REPORT) && targetType.equals(NODE_TYPE.REPORT_GROUP)) {
     //move
     Long sourceId = (Long) source.getItemProperty("id").getValue();
     Long targetId = (Long) target.getItemProperty("id").getValue();
     ZebraReport report = ((MyVaadinApplication) getApplication()).getPersistence().find(sourceId, ZebraReport.class);
     ZebraReportGroup group = ((MyVaadinApplication) getApplication()).getPersistence().find(targetId, ZebraReportGroup.class);
     group.addReport(g, getPersistence());
     reload();
     getApplication().getMainWindow().showNotification("Bericht verschoben", "Der Bericht wurde erfolgreich verschoben.", Window.Notification.TYPE_TRAY_NOTIFICATION);
     } else if (sourceType.equals(NODE_TYPE.SHARED_REPORT) && targetType.equals(NODE_TYPE.REPORT_GROUP)) {
     Long sourceId = (Long) source.getItemProperty("id").getValue();
     Long targetId = (Long) target.getItemProperty("id").getValue();
     ZebraReportAccessGrant report = ((MyVaadinApplication) getApplication()).getPersistence().find(sourceId, ZebraReportAccessGrant.class);
     ZebraReportGroup group = ((MyVaadinApplication) getApplication()).getPersistence().find(targetId, ZebraReportGroup.class);
     group.addReport(report, getPersistence());
     reload();
     getApplication().getMainWindow().showNotification("Bericht verschoben", "Der Bericht wurde erfolgreich verschoben.", Window.Notification.TYPE_TRAY_NOTIFICATION);
     } else {
     getApplication().getMainWindow().showNotification("Warnung", "Dieses Element kann nicht verschoben werden.", Window.Notification.TYPE_WARNING_MESSAGE);
     }
     }
     */
    public void reload() {
        if (currentView.equals(VIEW_TYPE.REPORT)) {
            // hsplit.setSecondComponent(reportRenderPanel);
            initializeReportTree();
        } else if (currentView.equals(VIEW_TYPE.MANAGEMENT)) {
            initializeManagementTree();
        }
        //expand all nodes
        for (Iterator<?> it = objectTree.rootItemIds().iterator(); it.hasNext();) {
            objectTree.expandItemsRecursively(it.next());
        }
    }

    private void initializeManagementTree() {
        objectTree.removeAllItems();
        ThemeResource rootResource = new ThemeResource("../zebra/img/star_yellow.png");
        ThemeResource userGroupResource = new ThemeResource("../zebra/img/users2.png");
        ThemeResource userGroupRequestResource = new ThemeResource("../zebra/img/users4_add.png");
        ThemeResource userResource = new ThemeResource("../zebra/img/pawn_glass_white.png");
        ThemeResource privUserResource = new ThemeResource("../zebra/img/pawn_glass_yellow.png");
        ThemeResource userAdminResource = new ThemeResource("../zebra/img/pawn_glass_red.png");

        Object rootId = objectTree.addItem();
        Item root = objectTree.getItem(rootId);
        root.getItemProperty("name").setValue("Deine Gruppen");
        root.getItemProperty("type").setValue(NODE_TYPE.MANAGEMENT_ROOT);
        root.getItemProperty("id").setValue(-1l);
        root.getItemProperty("icon").setValue(rootResource);
        ZebraUser user = (ZebraUser) getApplication().getUser();

        List<ZebraGroupMembership> memberships = ((MyVaadinApplication) getApplication()).getPersistence().getGroupMemberships(user);
        for (ZebraGroupMembership membership : memberships) {
            ZebraGroup group = membership.getUserGroup();
            Object groupId = objectTree.addItem();
            Item groupItem = objectTree.getItem(groupId);
            groupItem.getItemProperty("name").setValue(group.getName());
            if (!membership.isAccepted()) {
                groupItem.getItemProperty("type").setValue(NODE_TYPE.GROUP_INVITATION);
                groupItem.getItemProperty("icon").setValue(userGroupRequestResource);
            } else {
                groupItem.getItemProperty("type").setValue(NODE_TYPE.USER_GROUP);
                groupItem.getItemProperty("icon").setValue(userGroupResource);
            }
            groupItem.getItemProperty("id").setValue(group.getId());
            objectTree.setParent(groupId, rootId);
            if (membership.isAccepted()) {
                objectTree.setChildrenAllowed(groupId, true);
                //add users
                for (ZebraGroupMembership userMembership : group.getMemberships(true)) {
                    ZebraUser groupUser = userMembership.getReportUser();
                    ZebraRole role = userMembership.getRole();
                    Object userId = objectTree.addItem();
                    Item userItem = objectTree.getItem(userId);

                    userItem.getItemProperty("name").setValue(groupUser.getName());
                    userItem.getItemProperty("type").setValue(NODE_TYPE.USER);
                    userItem.getItemProperty("id").setValue(groupUser.getId());
                    switch (role) {
                        case ADMIN:
                            userItem.getItemProperty("icon").setValue(userAdminResource);
                            break;
                        case PRIVILEGED:
                            userItem.getItemProperty("icon").setValue(privUserResource);
                            break;
                        default:
                            userItem.getItemProperty("icon").setValue(userResource);
                    }

                    objectTree.setParent(userId, groupId);
                    objectTree.setChildrenAllowed(userId, false);
                }
            } else {
                objectTree.setChildrenAllowed(groupId, false);
            }
        }
    }

    private void initializeReportTree() {
        objectTree.removeAllItems();
        ThemeResource rootResource = new ThemeResource("../zebra/img/star_yellow.png");
        ThemeResource reportGroupResource = new ThemeResource("../zebra/img/folder.png");
        ZebraUser user = (ZebraUser) getApplication().getUser();
        Object rootId = objectTree.addItem();
        Item root = objectTree.getItem(rootId);
        root.getItemProperty("type").setValue(NODE_TYPE.REPORT_ROOT);
        root.getItemProperty("id").setValue(-1l);
        root.getItemProperty("icon").setValue(rootResource);
        objectTree.setChildrenAllowed(rootId, false);
        objectTree.select(rootId);
        List<ZebraReportGroup> groups = getPersistence().getReportGroups(user);
        int overallReports = ((BigInteger) getPersistence().performQueryForSingleValue(searchPanel.getReportCountQuery(user))).intValue();
        for (ZebraReportGroup group : groups) {
            Object groupId = objectTree.addItem();
            Item i = objectTree.getItem(groupId);
            int reports = ((BigInteger) getPersistence().performQueryForSingleValue(searchPanel.getReportCountQuery(user, group))).intValue();
            i.getItemProperty("name").setValue(group.getName() + " (" + reports + ")");
            i.getItemProperty("type").setValue(NODE_TYPE.REPORT_GROUP);
            i.getItemProperty("id").setValue(group.getId());
            i.getItemProperty("icon").setValue(reportGroupResource);
            objectTree.setChildrenAllowed(groupId, false);
        }
        root.getItemProperty("name").setValue("Alle Berichte " + " (" + overallReports + ")");
        loadReports();
    }

    private void loadReports() {
        ZebraUser user = (ZebraUser) getApplication().getUser();
        int reportCount;
        List<ZebraReportAccessGrant> reports;
        if (currentGroupId == -1l) {
            reportCount = ((BigInteger) getPersistence().performQueryForSingleValue(searchPanel.getReportCountQuery(user))).intValue();
            reports = getPersistence().performQueryForList(searchPanel.getReportsQuery(user), ZebraReportAccessGrant.class, currentReportPage * 10);
        } else {
            ZebraReportGroup group = getPersistence().find(currentGroupId, ZebraReportGroup.class);
            reportCount = ((BigInteger) getPersistence().performQueryForSingleValue(searchPanel.getReportCountQuery(user, group))).intValue();
            reports = getPersistence().performQueryForList(searchPanel.getReportsQuery(user, group), ZebraReportAccessGrant.class, currentReportPage * 10);
        }
        VerticalLayout l = new VerticalLayout();
        l.setMargin(true);
        l.setSizeFull();
        visibleReports.clear();
        for (ZebraReportAccessGrant report : reports) {
            ReportInfoPanel p = new ReportInfoPanel(report, user, getPersistence(), this);
            p.setWidth("100%");
            p.setHeight("45px");
            l.addComponent(p);
            visibleReports.add(p);
            Label spacer = new Label("<hr/>", Label.CONTENT_XHTML);
            l.addComponent(spacer);
            l.setComponentAlignment(p, Alignment.TOP_CENTER);
            l.setComponentAlignment(spacer, Alignment.TOP_CENTER);
        }
        int pages = reportCount / 10;
        if (reportCount % 10 > 0) {
            pages++;
        }

        final int availablePages = pages;
        HorizontalLayout navigation = new HorizontalLayout();
        final NativeButton first = new NativeButton("<<");
        first.setDescription("Erste Seite");
        first.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                currentReportPage = 0;
                loadReports();
            }
        });
        final NativeButton prev = new NativeButton("<");
        prev.setDescription("Vorherige Seite");
        prev.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                if (currentReportPage > 0) {
                    currentReportPage--;
                    loadReports();
                }
            }
        });
        final NativeButton next = new NativeButton(">");
        next.setDescription("Nächste Seite");
        next.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                if (currentReportPage + 1 < availablePages) {
                    currentReportPage++;
                    loadReports();
                }
            }
        });
        final NativeButton last = new NativeButton(">>");
        last.setDescription("Letzte Seite");
        last.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                currentReportPage = availablePages - 1;
                loadReports();
            }
        });
        first.setEnabled(!(currentReportPage == 0));
        prev.setEnabled(!(currentReportPage == 0));
        next.setEnabled(!(currentReportPage == availablePages - 1));
        last.setEnabled(!(currentReportPage == availablePages - 1));

        Label leftStop = new Label();
        NativeButton all = new NativeButton("Alle");
        all.setDescription("Alle Berichte auf der Seite auswählen");
        all.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                for (ReportInfoPanel panel : visibleReports) {
                    panel.setSelected(true);
                }
            }
        });
        navigation.addComponent(all);
        navigation.addComponent(leftStop);
        navigation.addComponent(first);
        navigation.addComponent(prev);

        int start = currentReportPage - 5;
        start = (start < 0) ? 0 : start;
        int end = start + 10;
        end = (end > pages) ? pages : end;

        if (end - start < 10 && pages > 10) {
            start = end - 10;
        }
        for (int i = start; i < end; i++) {
            if (i == currentReportPage) {
                Label pageLink = new Label("<b>" + Integer.toString(i + 1) + "</b>", Label.CONTENT_XHTML);
                pageLink.setStyleName("currentpage");
                pageLink.setWidth("15px");
                navigation.addComponent(pageLink);
                navigation.setComponentAlignment(pageLink, Alignment.MIDDLE_CENTER);
            } else {
                Link pageLink = new Link(Integer.toString(i + 1), null);
                navigation.addComponent(pageLink);
                navigation.setComponentAlignment(pageLink, Alignment.MIDDLE_CENTER);
            }
        }
        navigation.addComponent(next);
        navigation.addComponent(last);
        Label rightStop = new Label();
        navigation.addComponent(rightStop);
        navigation.setExpandRatio(leftStop, 1.0f);
        navigation.setExpandRatio(rightStop, 1.0f);
        navigation.setSpacing(true);

        navigation.setComponentAlignment(first, Alignment.MIDDLE_CENTER);
        navigation.setComponentAlignment(prev, Alignment.MIDDLE_CENTER);
        navigation.setComponentAlignment(next, Alignment.MIDDLE_CENTER);
        navigation.setComponentAlignment(last, Alignment.MIDDLE_CENTER);

        navigation.addListener(new LayoutClickListener() {
            public void layoutClick(LayoutClickEvent event) {

                // Get the child component which was clicked
                Component child = event.getChildComponent();

                if (child == null) {
                    // Not over any child component
                } else {
                    // Over a child component
                    if (child instanceof Link) {
                        currentReportPage = Integer.parseInt(((Link) child).getCaption()) - 1;
                        loadReports();
                    }
                }
            }
        });
        navigation.setWidth("100%");
        navigation.setHeight("25px");
        l.addComponent(navigation);
        l.setComponentAlignment(navigation, Alignment.BOTTOM_CENTER);
        l.setExpandRatio(navigation, 1.0f);
        hsplit.setSecondComponent(l);
    }

    public Action[] getActions(Object target, Object sender) {
        Item i = objectTree.getItem(target);
        if (i == null) {
            return null;
        }
        NODE_TYPE type = (NODE_TYPE) i.getItemProperty("type").getValue();
        switch (type) {
            case REPORT_GROUP:
                return new Action[]{READ_REPORT_ACTION, ADD_SELECTED_TO_GROUP_ACTION, DELETE_REPORT_GROUP_ACTION};
            case REPORT_ROOT:
                return new Action[]{READ_REPORT_ACTION, CREATE_REPORT_GROUP_ACTION, RELOAD_ACTION};
            case USER:
                return new Action[]{MODIFY_USER_ACTION, KICK_USER_ACTION};
            case USER_GROUP:
                return new Action[]{INVITE_USER_ACTION, LEAVE_GROUP_ACTION, DELETE_USER_GROUP_ACTION};
            case GROUP_INVITATION:
                return new Action[]{JOIN_GROUP_ACTION, WITHDRAW_INVITATION_ACTION};
            case MANAGEMENT_ROOT:
                return new Action[]{CREATE_USER_GROUP_ACTION, RELOAD_ACTION};
        }

        return null;
    }

    public void handleAction(Action action, Object sender, Object target) {
        if (action == READ_REPORT_ACTION) {
            performReadReportAction(target);
        } else if (action == RELOAD_ACTION) {
            reload();
        } else if (action == DELETE_REPORT_GROUP_ACTION) {
            performDeleteReportGroupAction(target);
        } else if (action == CREATE_REPORT_GROUP_ACTION) {
            performCreateReportGroupAction();
        } else if (action == ADD_SELECTED_TO_GROUP_ACTION) {
            performAddSelectionToGroupAction(target);
        } else if (action == CREATE_USER_GROUP_ACTION) {
            performCreateUserGroupAction();
        } else if (action == DELETE_USER_GROUP_ACTION) {
            performDeleteUserGroupAction(target);
        } else if (action == INVITE_USER_ACTION) {
            performInviteUserAction(target);
        } else if (action == JOIN_GROUP_ACTION) {
            performJoinGroupAction(target, true);
        } else if (action == WITHDRAW_INVITATION_ACTION) {
            performJoinGroupAction(target, false);
        } else if (action == LEAVE_GROUP_ACTION) {
            performLeaveGroupAction(target);
        } else if (action == KICK_USER_ACTION) {
            performKickUserAction(target);
        } else if (action == MODIFY_USER_ACTION) {
            performModifyUserAction(target);
        }
    }

    private void performDeleteReportGroupAction(Object pItemId) {
        Item i = objectTree.getItem(pItemId);
        if (i == null) {
            return;
        }

        Long id = (Long) i.getItemProperty("id").getValue();
        ZebraReportGroup group = getPersistence().find(id, ZebraReportGroup.class);
        group.delete(getPersistence());
        reload();
        getApplication().getMainWindow().showNotification("Gruppe gelöscht", "Die Berichtgruppe und alle Berichte wurden erfolgreich gelöscht.", Window.Notification.TYPE_TRAY_NOTIFICATION);
    }

    private void performReadReportAction(Object pItemId) {
        Item i = objectTree.getItem(pItemId);
        if (i == null) {
            return;
        }

        Long id = (Long) i.getItemProperty("id").getValue();
        final ZebraReportGroup selectedGroup = getPersistence().find(id, ZebraReportGroup.class);

        final ZebraUser user = (ZebraUser) getApplication().getUser();
        final Window w = new Window("Bericht einlesen");
        final ComboBox targetGroup = new ComboBox("Berichtgruppe");
        targetGroup.setWidth("100%");
        targetGroup.addContainerProperty("name", String.class, null);
        targetGroup.setItemCaptionPropertyId("name");

        Item noSelection = targetGroup.addItem(-1l);
        noSelection.getItemProperty("name").setValue("Keine Gruppe");
        targetGroup.setNullSelectionItemId(-1l);
        List<ZebraReportGroup> groups = getPersistence().getReportGroups(user);
        for (ZebraReportGroup group : groups) {
            Item groupItem = targetGroup.addItem(group.getId());
            groupItem.getItemProperty("name").setValue(group.getName());
        }
        if (selectedGroup != null) {
            targetGroup.select(selectedGroup.getId());
        }

        final TextArea reportContent = new TextArea("Bericht");
        reportContent.setWidth("400px");
        reportContent.setHeight("400px");
        reportContent.setNullRepresentation("");
        reportContent.setImmediate(true);
        reportContent.setInputPrompt("Bitte Berichtdaten einfügen. Dafür die Berichtseite per STRG+A markieren, per STRG+C kopieren und hier per STRG+V einfügen.");

        Button create = new Button("Einlesen");
        create.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                String report = (String) reportContent.getValue();
                try {
                    Long targetGroupId = (Long) targetGroup.getValue();
                    ZebraReportGroup targetGroup = null;
                    if (targetGroupId != null && targetGroupId != -1l) {
                        targetGroup = getPersistence().find(targetGroupId, ZebraReportGroup.class);
                    }
                    //for (int i = 0; i < 400; i++) {
                    //  System.out.println("ADD " + i);
                    ZebraReportParser parser = new ZebraReportParser(getPersistence(), "zz2");
                    ZebraReport rep = parser.parse(report);
                    rep.setOwner(user);
                    ZebraReportAccessGrant grant = new ZebraReportAccessGrant();
                    grant.setReport(rep);
                    grant.setUser(user);
                    grant.setOwner(true);

                    getPersistence().persist(rep);
                    getPersistence().persist(grant);
                    if (targetGroup != null) {
                        targetGroup.addReport(grant, getPersistence());
                    }
                    //  }
                    loadReports();
                    getApplication().getMainWindow().showNotification("Bericht eingelesen", "Der Bericht wurde erfolgreich eingelesen.", Window.Notification.TYPE_TRAY_NOTIFICATION);
                    reportContent.setValue("");
                } catch (ParserException pe) {
                    getApplication().getMainWindow().showNotification("Fehler", "Der Bericht konnte nicht eingelesen werden. Ursache: " + pe.getMessage(), Window.Notification.TYPE_WARNING_MESSAGE);
                }
            }
        });
        Button cancel = new Button("Schließen");
        cancel.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                getApplication().getMainWindow().removeWindow(w);
            }
        });
        GridLayout layout = new UIUtil.GridLayoutBuilder(2, 3).
                addComponent(targetGroup, 0, 0, 2, 1).
                addComponent(reportContent, 0, 1, 2, 1).
                addComponent(create, 0, 2, 1, 1).addComponent(cancel, 1, 2, 1, 1).
                getLayout();
        layout.setComponentAlignment(create, Alignment.MIDDLE_LEFT);
        layout.setComponentAlignment(cancel, Alignment.MIDDLE_RIGHT);
        layout.setSpacing(true);
        layout.setMargin(true);
        w.setContent(layout);
        w.center();
        getApplication().getMainWindow().addWindow(w);
    }

    private void performAddSelectionToGroupAction(Object pItemId) {
        Item i = objectTree.getItem(pItemId);
        if (i == null) {
            return;
        }

        Long id = (Long) i.getItemProperty("id").getValue();
        ZebraReportGroup group = getPersistence().find(id, ZebraReportGroup.class);
        boolean reload = false;
        for (ReportInfoPanel p : visibleReports) {
            if (p.isSelected()) {
                group.addReport(p.getReportAccessGrant(), getPersistence());
                reload = true;
            }
        }
        if (reload) {
            reload();
            getApplication().getMainWindow().showNotification("Berichte verschoben", "Die gewählten Berichte wurden erfolgreich in die Gruppe verschoben.", Window.Notification.TYPE_TRAY_NOTIFICATION);
        } else {
            getApplication().getMainWindow().showNotification("Warnung", "Es sind keine Berichte ausgewählt..", Window.Notification.TYPE_WARNING_MESSAGE);
        }
    }

    private void performDeleteSharesAction(Object pItemId) {
//        Item i = objectTree.getItem(pItemId);
//        if (i == null) {
//            getApplication().getMainWindow().showNotification("Fehler", "Ungültige Auswahl.", Window.Notification.TYPE_ERROR_MESSAGE);
//            return;
//        }
//
//        Long id = (Long) i.getItemProperty("id").getValue();
//        NODE_TYPE type = (NODE_TYPE) i.getItemProperty("type").getValue();
//        if (type.equals(NODE_TYPE.REPORT)) {
//            final ZebraReport report = getPersistence().find(id, ZebraReport.class);
//            List<ZebraReportAccessGrant> shares = getPersistence().getShares(report);
//            for (ZebraReportAccessGrant share : shares) {
//                ZebraShareGroupMapping mapping = share.getGroupMapping();
//                if (mapping != null) {
//                    mapping.getGroup().removeReport(share, getPersistence());
//                }
//                getPersistence().remove(share);
//            }
//        } else if (type.equals(NODE_TYPE.SHARED_REPORT)) {
//            final ZebraReportAccessGrant share = getPersistence().find(id, ZebraReportAccessGrant.class);
//            ZebraShareGroupMapping mapping = share.getGroupMapping();
//            if (mapping != null) {
//                mapping.getGroup().removeReport(share, getPersistence());
//            }
//            getPersistence().remove(share);
//        }
//        reload();
    }

    private void performCreateReportGroupAction() {
        final ZebraUser user = (ZebraUser) getApplication().getUser();
        final Window w = new Window("Berichtgruppe erstellen");
        final TextField groupName = new TextField("Gruppenname");
        groupName.setWidth("100%");
        groupName.setRequired(true);
        StringLengthValidator v = new StringLengthValidator("Der Gruppenname muss länger als 3 Zeichen sein.");
        v.setMinLength(3);
        groupName.addValidator(v);
        Button create = new Button("Gruppe erstellen");
        create.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                if (groupName.isValid()) {
                    String name = (String) groupName.getValue();
                    ZebraReportGroup group = new ZebraReportGroup();
                    group.setName(name);
                    group.setOwner(user);
                    getPersistence().persist(group);
                    getApplication().getMainWindow().removeWindow(w);
                    reload();
                    getApplication().getMainWindow().showNotification("Gruppe erstellt", "Die Berichtgruppe wurde erfolgreich erstellt.", Window.Notification.TYPE_TRAY_NOTIFICATION);
                }
            }
        });
        Button cancel = new Button("Abbrechen");
        cancel.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                getApplication().getMainWindow().removeWindow(w);
            }
        });
        GridLayout layout = new UIUtil.GridLayoutBuilder(2, 2).
                addComponent(groupName, 0, 0, 2, 1).
                addComponent(create, 0, 1, 1, 1).addComponent(cancel, 1, 1, 1, 1).
                getLayout();
        layout.setSpacing(true);
        layout.setMargin(true);
        w.setContent(layout);
        w.center();
        getApplication().getMainWindow().addWindow(w);
    }

    private void performCreateUserGroupAction() {
        final ZebraUser user = (ZebraUser) getApplication().getUser();
        final Window w = new Window("Benutzergruppe erstellen");
        final TextField groupName = new TextField("Gruppenname");
        groupName.setWidth("100%");
        groupName.setRequired(true);
        StringLengthValidator v = new StringLengthValidator("Der Gruppenname muss länger als 3 Zeichen sein.");
        v.setMinLength(3);
        groupName.addValidator(v);
        Button create = new Button("Gruppe erstellen");
        create.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                if (groupName.isValid()) {
                    String name = (String) groupName.getValue();
                    if (getPersistence().getUserGroup(name) != null) {
                        getApplication().getMainWindow().showNotification("Gruppe existiert", "Eine Benutzergruppe mit dem gewählten Namen existiert bereits.", Window.Notification.TYPE_WARNING_MESSAGE);
                        return;
                    }
                    ZebraGroup group = new ZebraGroup();
                    group.setName(name);
                    getPersistence().persist(group);
                    group.addAdmin(user, getPersistence());
                    getApplication().getMainWindow().removeWindow(w);
                    reload();
                    getApplication().getMainWindow().showNotification("Gruppe erstellt", "Die Benutzergruppe wurde erfolgreich erstellt.", Window.Notification.TYPE_TRAY_NOTIFICATION);
                }
            }
        });
        Button cancel = new Button("Abbrechen");
        cancel.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                getApplication().getMainWindow().removeWindow(w);
            }
        });
        GridLayout layout = new UIUtil.GridLayoutBuilder(2, 2).
                addComponent(groupName, 0, 0, 2, 1).
                addComponent(create, 0, 1, 1, 1).addComponent(cancel, 1, 1, 1, 1).
                getLayout();
        layout.setSpacing(true);
        layout.setMargin(true);
        w.setContent(layout);
        w.center();
        getApplication().getMainWindow().addWindow(w);
    }

    private void performDeleteUserGroupAction(Object pItemId) {
        final ZebraUser user = (ZebraUser) getApplication().getUser();

        Item i = objectTree.getItem(pItemId);
        if (i == null) {
            getApplication().getMainWindow().showNotification("Fehler", "Ungültige Auswahl.", Window.Notification.TYPE_ERROR_MESSAGE);
            return;
        }

        Long id = (Long) i.getItemProperty("id").getValue();
        final ZebraGroup group = getPersistence().find(id, ZebraGroup.class);

        if (!group.isAdmin(user)) {
            getApplication().getMainWindow().showNotification("Keine Adminrechte", "Du hast nicht die notwendigen Rechte um diese Gruppe aufzulösen.", Window.Notification.TYPE_WARNING_MESSAGE);
            return;
        }

        final Window w = new Window("Gruppe auflösen");

        final Label message = new Label("Willst du die gewählte Gruppe wirklich auflösen? Beim Auflösen einer Gruppe werden alle Mitglieder entlassen. Berichtfreigaben bleiben erhalten.");
        message.setWidth("100%");
        Button create = new Button("Gruppe auflösen");
        create.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                group.delete(getPersistence());
                getApplication().getMainWindow().removeWindow(w);
                reload();
                getApplication().getMainWindow().showNotification("Gruppe aufgelöst", "Die Gruppe wurde erfolgreich aufgelöst.", Window.Notification.TYPE_TRAY_NOTIFICATION);
            }
        });
        Button cancel = new Button("Abbrechen");
        cancel.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                getApplication().getMainWindow().removeWindow(w);
            }
        });
        GridLayout layout = new UIUtil.GridLayoutBuilder(2, 2).
                addComponent(message, 0, 0, 2, 1).
                addComponent(create, 0, 1, 1, 1).addComponent(cancel, 1, 1, 1, 1).
                getLayout();
        layout.setSpacing(true);
        layout.setMargin(true);
        w.setContent(layout);
        w.center();
        getApplication().getMainWindow().addWindow(w);
    }

    private void performInviteUserAction(Object pItemId) {
        final ZebraUser user = (ZebraUser) getApplication().getUser();

        Item i = objectTree.getItem(pItemId);
        if (i == null) {
            getApplication().getMainWindow().showNotification("Fehler", "Ungültige Auswahl.", Window.Notification.TYPE_ERROR_MESSAGE);
            return;
        }

        Long id = (Long) i.getItemProperty("id").getValue();
        final ZebraGroup group = getPersistence().find(id, ZebraGroup.class);

        if (!group.isPrivileged(user)) {
            getApplication().getMainWindow().showNotification("Keine Einladerechte", "Du hast nicht die notwendigen Rechte um Benutzer in diese Gruppe einzuladen.", Window.Notification.TYPE_WARNING_MESSAGE);
            return;
        }

        final Window w = new Window("Benutzer einladen");
        final TextField userName = new TextField("Benutzername");
        userName.setWidth("100%");
        StringLengthValidator v = new StringLengthValidator("Der Benutzername muss länger als 3 Zeichen sein.");
        v.setMinLength(3);
        userName.addValidator(v);
        userName.setRequired(true);
        Button create = new Button("Benutzer einladen");
        create.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                if (userName.isValid()) {
                    String name = (String) userName.getValue();
                    ZebraUser newMember = getPersistence().findUserByName(name);
                    if (newMember == null) {
                        getApplication().getMainWindow().showNotification("Benutzer nicht gefunden", "Es existiert kein Benutzer mit dem angegebenen Namen.", Window.Notification.TYPE_WARNING_MESSAGE);
                        return;
                    }
                    if (!group.addMember(newMember, getPersistence())) {
                        getApplication().getMainWindow().showNotification("Benutzer nicht hinzugefügt", "Der Benutzer kann nicht eingeladen werden. Möglicherweise ist er bereites Mitglied der Gruppe.", Window.Notification.TYPE_WARNING_MESSAGE);
                        return;
                    }
                    getApplication().getMainWindow().removeWindow(w);
                    reload();
                    getApplication().getMainWindow().showNotification("Benutzer eingeladen", "Der Benutzer wurde erfolgreich eingeladen.", Window.Notification.TYPE_TRAY_NOTIFICATION);
                }
            }
        });
        Button cancel = new Button("Abbrechen");
        cancel.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                getApplication().getMainWindow().removeWindow(w);
            }
        });
        GridLayout layout = new UIUtil.GridLayoutBuilder(2, 2).
                addComponent(userName, 0, 0, 2, 1).
                addComponent(create, 0, 1, 1, 1).addComponent(cancel, 1, 1, 1, 1).
                getLayout();
        layout.setSpacing(true);
        layout.setMargin(true);
        w.setContent(layout);
        w.center();
        getApplication().getMainWindow().addWindow(w);
    }

    private void performJoinGroupAction(Object pItemId, boolean pAccept) {
        final ZebraUser user = (ZebraUser) getApplication().getUser();

        Item i = objectTree.getItem(pItemId);

        if (i == null) {
            getApplication().getMainWindow().showNotification("Fehler", "Ungültige Auswahl.", Window.Notification.TYPE_ERROR_MESSAGE);
            return;
        }

        Long id = (Long) i.getItemProperty("id").getValue();
        final ZebraGroup group = getPersistence().find(id, ZebraGroup.class);
        if (pAccept) {
            user.acceptGroupInvitation(group, getPersistence());
            getApplication().getMainWindow().showNotification("Gruppe beigetreten", "Du bist der Gruppe erfolgreich beigetreten.", Window.Notification.TYPE_TRAY_NOTIFICATION);
        } else {
            user.leaveGroup(group, getPersistence());
            getApplication().getMainWindow().showNotification("Einladung abgelehnt", "Die Gruppeneinladung wurde erfolgreich abgelehnt.", Window.Notification.TYPE_TRAY_NOTIFICATION);
        }
        reload();
    }

    private void performLeaveGroupAction(Object pItemId) {
        final ZebraUser user = (ZebraUser) getApplication().getUser();

        Item i = objectTree.getItem(pItemId);
        if (i == null) {
            getApplication().getMainWindow().showNotification("Fehler", "Ungültige Auswahl.", Window.Notification.TYPE_ERROR_MESSAGE);
            return;
        }

        Long id = (Long) i.getItemProperty("id").getValue();
        final ZebraGroup group = getPersistence().find(id, ZebraGroup.class);

        if (group.isLastAdmin(user)) {
            getApplication().getMainWindow().showNotification("Verlassen nicht möglich", "Der letzte Administrator einer Gruppe kann diese nicht verlassen. Gib zuerst einem anderen Benutzer Administratorrechte oder löse die Gruppe auf.", Window.Notification.TYPE_WARNING_MESSAGE);
            return;
        }

        final Window w = new Window("Gruppe verlassen");

        final Label message = new Label("Willst du die gewählte Gruppe wirklich verlassen?");
        message.setWidth("100%");
        Button create = new Button("Gruppe verlassen");
        create.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                group.removeUser(user, getPersistence());
                getApplication().getMainWindow().removeWindow(w);
                reload();
                getApplication().getMainWindow().showNotification("Gruppe verlassen", "Du hast die Gruppe erfolgreich verlassen.", Window.Notification.TYPE_TRAY_NOTIFICATION);
            }
        });
        Button cancel = new Button("Abbrechen");
        cancel.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                getApplication().getMainWindow().removeWindow(w);
            }
        });
        GridLayout layout = new UIUtil.GridLayoutBuilder(2, 2).
                addComponent(message, 0, 0, 2, 1).
                addComponent(create, 0, 1, 1, 1).addComponent(cancel, 1, 1, 1, 1).
                getLayout();
        layout.setSpacing(true);
        layout.setMargin(true);
        w.setContent(layout);
        w.center();
        getApplication().getMainWindow().addWindow(w);
    }

    private void performModifyUserAction(Object pItemId) {
        final ZebraUser user = (ZebraUser) getApplication().getUser();

        Item i = objectTree.getItem(pItemId);
        if (i == null) {
            getApplication().getMainWindow().showNotification("Fehler", "Ungültige Auswahl.", Window.Notification.TYPE_ERROR_MESSAGE);
            return;
        }

        Long id = (Long) i.getItemProperty("id").getValue();
        final ZebraUser userToModify = getPersistence().find(id, ZebraUser.class);

        if (user.getId() == userToModify.getId()) {
            getApplication().getMainWindow().showNotification("Netter Versuch...", "deine eigenen Rechte kannst du nicht bearbeiten.", Window.Notification.TYPE_WARNING_MESSAGE);
            return;
        }

        Object groupItemId = objectTree.getParent(pItemId);
        Item groupItem = objectTree.getItem(groupItemId);
        Long groupId = (Long) groupItem.getItemProperty("id").getValue();
        final ZebraGroup group = getPersistence().find(groupId, ZebraGroup.class);

        if (!user.isAdmin(group)) {
            getApplication().getMainWindow().showNotification("Keine Administratorrechte", "Nur Gruppenadministratoren können Benutzerrechte bearbeiten.", Window.Notification.TYPE_WARNING_MESSAGE);
            return;
        }

        final Window w = new Window("Benutzerrechte bearbeiten");

        final ComboBox roleBox = new ComboBox("Rechte");
        final Label description = new Label();
        description.setWidth("100%");
        description.setImmediate(true);

        roleBox.setNullSelectionAllowed(false);
        roleBox.setImmediate(true);
        roleBox.setWidth("100%");

        ZebraRole currentRole = userToModify.getRole(group);
        if (currentRole == null) {
            getApplication().getMainWindow().showNotification("Fehler", "Ungültige Benutzerrechte.", Window.Notification.TYPE_ERROR_MESSAGE);
            return;
        }

        if (!currentRole.equals(ZebraRole.MEMBER)) {
            roleBox.addItem(ZebraRole.MEMBER);
            roleBox.select(ZebraRole.MEMBER);
            description.setValue(ZebraRole.MEMBER.getDescription());
        }

        if (!currentRole.equals(ZebraRole.PRIVILEGED)) {
            roleBox.addItem(ZebraRole.PRIVILEGED);
            roleBox.select(ZebraRole.PRIVILEGED);
            description.setValue(ZebraRole.PRIVILEGED.getDescription());
        }

        if (!currentRole.equals(ZebraRole.ADMIN)) {
            roleBox.addItem(ZebraRole.ADMIN);
            roleBox.select(ZebraRole.ADMIN);
            description.setValue(ZebraRole.ADMIN.getDescription());
        }

        roleBox.addListener(new Property.ValueChangeListener() {
            public void valueChange(ValueChangeEvent event) {
                ZebraRole role = (ZebraRole) roleBox.getValue();
                description.setValue(role.getDescription());
            }
        });

        Button create = new Button("Rechte zuweisen");
        create.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                if (!group.grantRole(userToModify, (ZebraRole) roleBox.getValue(), getPersistence())) {
                    getApplication().getMainWindow().showNotification("Keine Änderung", "Die Benutzerrechte konnten nicht geändert werden. Möglicherweise besitzt der Benutzer bereits die gewählten Rechte.", Window.Notification.TYPE_WARNING_MESSAGE);
                    return;
                }
                getApplication().getMainWindow().removeWindow(w);
                reload();
                getApplication().getMainWindow().showNotification("Benutzerrechte geändert", "Dem Benutzer wurden erfolgreich die neuen Rechte zugewiesen.", Window.Notification.TYPE_TRAY_NOTIFICATION);
            }
        });
        Button cancel = new Button("Abbrechen");
        cancel.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                getApplication().getMainWindow().removeWindow(w);
            }
        });
        GridLayout layout = new UIUtil.GridLayoutBuilder(2, 3).
                addComponent(roleBox, 0, 0, 2, 1).
                addComponent(description, 0, 1, 2, 1).
                addComponent(create, 0, 2, 1, 1).addComponent(cancel, 1, 2, 1, 1).
                getLayout();
        layout.setSpacing(true);
        layout.setMargin(true);
        w.setContent(layout);
        w.center();
        getApplication().getMainWindow().addWindow(w);
    }

    private void performKickUserAction(Object pItemId) {
        final ZebraUser user = (ZebraUser) getApplication().getUser();

        Item userItem = objectTree.getItem(pItemId);
        if (userItem == null) {
            getApplication().getMainWindow().showNotification("Fehler", "Ungültige Auswahl.", Window.Notification.TYPE_ERROR_MESSAGE);
            return;
        }

        Long userId = (Long) userItem.getItemProperty("id").getValue();

        if (userId == user.getId()) {
            getApplication().getMainWindow().showNotification("Ähm...", "du kannst dich nicht selbst entlassen.", Window.Notification.TYPE_WARNING_MESSAGE);
            return;
        }

        final ZebraUser userToKick = getPersistence().find(userId, ZebraUser.class);

        Object groupItemId = objectTree.getParent(pItemId);
        Item groupItem = objectTree.getItem(groupItemId);
        Long groupId = (Long) groupItem.getItemProperty("id").getValue();
        final ZebraGroup group = getPersistence().find(groupId, ZebraGroup.class);

        if (!user.isAdmin(group)) {
            getApplication().getMainWindow().showNotification("Keine Adminrechte", "Nur Administratoren können Mitglieder entlassen.", Window.Notification.TYPE_WARNING_MESSAGE);
            return;
        }

        final Window w = new Window("Benutzer entlassen");

        final Label message = new Label("Willst du den gewählten Benutzer wirklich entlassen?");
        message.setWidth("100%");
        Button create = new Button("Benutzer entlassen");
        create.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                group.removeUser(userToKick, getPersistence());
                getApplication().getMainWindow().removeWindow(w);
                reload();
                getApplication().getMainWindow().showNotification("Benutzer entlassen", "Du den Benutzer erfolgreich entlassen.", Window.Notification.TYPE_TRAY_NOTIFICATION);
            }
        });
        Button cancel = new Button("Abbrechen");
        cancel.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                getApplication().getMainWindow().removeWindow(w);
            }
        });
        GridLayout layout = new UIUtil.GridLayoutBuilder(2, 2).
                addComponent(message, 0, 0, 2, 1).
                addComponent(create, 0, 1, 1, 1).addComponent(cancel, 1, 1, 1, 1).
                getLayout();
        layout.setSpacing(true);
        layout.setMargin(true);
        w.setContent(layout);
        w.center();
        getApplication().getMainWindow().addWindow(w);
    }
}
